[trainer, worker, fsdp, cfg, tests] feat: add multi-role distillation runtime - #546
Conversation
… runtime Bind the generic distillation control plane to colocated FSDP role groups with independent optimizer state, named-LoRA role switching, EMA, profiling metrics, and atomic composite checkpoint/resume. Preserve an independent-module correctness path and fail closed at deferred architecture and adversarial boundaries. Refs: verl-project#519 AI assistance (OpenAI Codex) was used for this change. Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: NancyFyong <2742092809@qq.com>
Match the established worker profiler setup so nested tool settings are converted from OmegaConf before DistProfiler construction. This prevents production distillation workers from failing during actor initialization. AI assistance (OpenAI Codex) was used for this change. Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: NancyFyong <2742092809@qq.com>
Resolve DataProtoFuture values returned by nonblocking worker dispatch before the driver converts phase metrics and optimizer counters. This lets the real Ray data plane complete a distillation cycle. AI assistance (OpenAI Codex) was used for this change. Co-authored-by: OpenAI Codex <noreply@openai.com> Signed-off-by: NancyFyong <2742092809@qq.com>
…stabilize resume Resolve phase RPC failures before collecting lazy rank metadata, construct only the actor subconfigs needed by distillation, and fingerprint plans through canonical JSON rather than order-dependent repr strings. Keep newly introduced helpers flat and descriptively named. Inspect fake adapters directly in isolation tests instead of using inference export. Validation: 449 CPU regressions, both one-rank FSDP role/checkpoint tests, generated-config verification, and all pre-commit hooks passed. Refs verl-project#535 AI assistance (OpenAI via pi) was used for this change. Co-authored-by: OpenAI <noreply@openai.com> Signed-off-by: NancyFyong <2742092809@qq.com>
Carry the PR 1 controller naming through checkpoint state handling and tests after rebasing the multi-role runtime. Keep framework-defined private hooks unchanged. AI assistance (OpenAI via pi) was used for this change. Co-authored-by: OpenAI <noreply@openai.com> Signed-off-by: NancyFyong <2742092809@qq.com>
80d7b92 to
ddbcd4e
Compare
…utionMatchingComputer The architecture-owned differentiable computation object misused the *Runner suffix, which in this repo denotes a top-level task entrypoint (TaskRunner, RayTrainerTaskRunner). Rename it to match the algorithm family it belongs to and the DistributionMatchingModelAdapter that builds it: DistillationPhaseRunner -> DistributionMatchingComputer (Protocol) build_distillation_phase_runner-> build_distribution_matching_computer (hook) self.phase_runner -> self.dm_computer (worker attr) phase_runner_rank_*.pt -> dm_computer_rank_*.pt (per-rank state) The control-plane phase contracts (PhaseRequest, PhaseResult, UpdatePhaseSpec, DistillationPhaseExecutor) and the compute_phase method are deliberately kept, since a cycle is genuinely modelled as student/fake phases. Renaming the per-rank state file changes resume compatibility for pre-existing checkpoints. Validated in the required environment: 449 focused trainer/worker CPU tests pass; ruff, mypy, generated-config verification and all staged pre-commit hooks pass. Co-authored-by: OpenAI Codex Signed-off-by: NancyFyong <2742092809@qq.com>
…-batches Allow architecture computers to declare an explicit loss denominator. Accumulate numerator gradients and normalize over data-parallel counts before clipping and stepping; preserve sample means by default. Validation: 470 targeted CPU tests passed; applicable pre-commit hooks, config regeneration, and diff checks passed. AI assistance (pi coding agent) was used for this change. Co-authored-by: pi coding agent Signed-off-by: NancyFyong <2742092809@qq.com>
Merge distillation-acceleration without rewriting published history. The resulting tree is identical to the CPU-tested repair snapshot. AI assistance (pi coding agent) was used for this change. Co-authored-by: pi coding agent Signed-off-by: NancyFyong <2742092809@qq.com>
Merge the updated PR1 baseline without dropping main's merged-weight streaming path or the role-aware adapter selection and PEFT metadata. Keep CPU export fixtures independent of GPU memory probes and exercise implicit default, explicit default, student, and student EMA adapters. Validation: 1,441 L1 CPU tests, 14 focused LoRA export tests, and the config-doc test pass. Generated configs are stable and all changed-file pre-commit hooks pass. AI assistance (ChatGPT via Pi) was used for this change. Co-authored-by: ChatGPT (via Pi) Signed-off-by: NancyFyong <2742092809@qq.com>
Proposal: share the existing OPD configuration, keep the DMD execution flowFor #545 and this PR (RFC #519 / #535), would it make sense to consolidate further around the existing At Suggested boundary:
Illustrative target configuration, not supported by the current head: algorithm:
trainer_type: distillation
sample_source: offline
distillation:
enabled: true
nnodes: 0
teacher_models:
teacher_model:
model_path: ${actor_rollout_ref.model.path}
distribution_matching:
recipe: dmd2
fake_update_ratio: 2
role_storage: shared_base_adaptersSharing configuration would not mean sending DMD through the PPO update loop or treating OPD's For a bounded first change, I suggest a single colocated teacher. Roles may share a physical base only when their checkpoint/configuration identities are compatible; a different teacher must occupy an explicitly supported separate group, not silently use the student's base. Unsupported DMD multi-teacher routing, standalone teacher pools and OPD Compatibility tests should preserve existing OPD behavior, explicitly handle legacy DMD configs with Would you support making this consolidation in #545/#546 before merge? In particular, does sharing the teacher/configuration infrastructure while retaining the DMD-specific execution flow and subconfiguration look like the right boundary? No implementation changes have been made for this proposal yet. |
What does this PR do?
PR 2 of RFC #519: distributed role execution, independent student/fake-score optimizers and schedulers, LoRA/EMA, and composite checkpoint/resume. Runtime specification: #535.
Stacked on
distillation-acceleration/ #545; review the incremental diff against that parent. This is not a runnable model recipe: a separate architecture adapter must supply conditioning, forwards, score conversion, and differentiable student computation.Checklist Before Starting
[{modules}] {type}: {description}.This is #519's runtime layer, not a second controller or OPD trainer. It preserves OPD (#293, #495) and reuses existing trainer/FSDP foundations, adding independent fake-score optimization and multi-role state management.
Test
Local results at
28e2943, based on PR 11ef230a, using Python 3.12.13 / PyTorch 2.13.0+cu129 in theverlomnienvironment:CPU coverage includes dispatch/futures, typed configs, sample/element accumulation, gradient ownership, finite-step accounting, EMA/export, and checkpoint fingerprints, using fake workers where appropriate.
Limits: historical one-rank FSDP1/FSDP2 evidence in #535 was not rerun for this head. The denominator collective still needs real multi-rank validation; no current-head production-training or inference-parity claim is made. Remote CPU CI only targets
main/v0.*bases, so this stacked PR's CPU results are local.Validation commands
Run from the PR checkout with the project environment active:
--filesavoids a local Git incompatibility with--all-files.API and Usage Example
Configuration fragment for a separately registered architecture adapter, not a standalone launch recipe:
offlinebypasses external RL rollout; student computation stays inside training.distillation.enabledremains OPD-only. Exportingstudentleaves EMA in resumable state.The opt-in
DistributionMatchingModelAdapter.build_distribution_matching_computer(model_config, plan)returns aDistributionMatchingComputerwith:compute_phase(request, batch, runtime)→DistillationPhaseComputation: one graph-bearing scalar loss for the requested role plus detached metrics;state_dict()/load_state_dict(state): checkpointable sampling/RNG state.The computer owns model math; the runtime owns optimization. Existing
DiffusionModelBaseadapters gain no new mandatory abstract methods.Design & Code Changes
Ownership and reuse
trainer/diffusion/distillation/ray_trainer.pyworkers/diffusion_distillation_worker.pyworkers/engine/fsdp/distillation_impl.pypipelines/model_base.pyPaths are relative to
verl_omni/. The worker reuses verl dispatch/profiling andEngineRegistry, not a new loading backend or PPO-shaped execution.Roles vs. storage:
shared_base_adaptersuses one frozen base with student/fake-score/EMA adapters and an adapter-disabled teacher.colocated_independentuses separate physical groups as the full-module fallback/correctness baseline. Sharing is not an algorithm requirement. Both layouts are colocated; shared storage requires LoRA, and shared FSDP1 requiresuse_orig_params=true.One optimizer owner per phase: accumulate micro-batches, reject inactive-role gradients, normalize/clip, then step. Scheduler and eligible EMA updates require a finite successful step. Student/fake micro-batches and scheduler horizons are independent; PPO batch fields are not repurposed.
With
loss_normalizer=None, accumulation uses sample means. An explicit positive count accumulates numerator gradients and divides by the DP-averaged denominator before clipping. Invalid/mixed modes fail closed; this does not imply globally element-weighted aggregation for every metric.Architecture boundary: during a student phase, no-grad teacher/fake scoring must preserve the pending student graph; the score branches are detached. Role contexts restore adapter and train/eval state. Phase RPCs are blocking; computers still own synchronization of collective-dependent forward counts and branches.
Checkpoint vs. export: completed-cycle checkpoints atomically publish role groups, optimizers/schedulers, EMA, computer/driver RNG, dataloader and controller state. Persisted models are saved once per physical group; frozen teacher-only groups reload their base. Canonical fingerprints reject plan/config/layout drift. Publication is atomic; failed updates/restores are not in-memory rollback transactions.
Export selects
studentorstudent_emawith its own PEFT config and restores the previous adapter. Upstream merged-default export remains intact; named adapters are not silently substituted. This does not implement CheckpointEngine transfers or validation replicas.Not included: architecture-specific training/generation, adversarial multi-optimizer phases, causal/KV-cache execution, standalone score transport, inference orchestration, HDFS restore, or automatic checkpoint retention. Model integration begins with #543; later RFC stages supply the remaining capabilities.
Checklist Before Submitting
AI assistance: Claude and OpenAI via pi assisted implementation, tests, and review. The human submitter previously confirmed line-by-line review and testing of the earlier changes; the latest delta still needs final review.